Public and protected parts of B are 'private' in D_priv, and are 'protected' in D_prot. In D_publ, public parts of B are public (D_prot is-a-kind-of-a B), and protected parts of B remain protected in D_publ. Naturally *none* of the subclasses can access anything that is private in B. Class 'Client' can't even access the protected parts of B (ie: it's 'sealed off').
It is often the case that you want to make some but not all inherited member functions public in privately/protectedly derived classes. Ex: to make member fn B::f(int,char,float) public in D_prot, you would say:
class D_prot : protected B {
//...
public:
B::f; //note: not B::f(int,char,float)
};
There are limitations to this technique (can't distinguish overloaded names, and you can't make a feature that was 'protected' in the base 'public' in the derived). Where necessary, you can get around these by a call-through fn:
class D_prot : protected B {
public:
short f(int i, char c, float f) { return B::f(i,c,f); }